//
// RTSPResponse.h
//
// $Id: //base/include/RTSPResponse.h
//
// Library: base
// Package: RTSP
// Module : RTSPResponse
// Author :	Jelin,doitsjz@163.com
// Date	  :	10/30/2012
// 
// Definition of the RTSPResponse class.
//
// Copyright (c) 2012-2012, iGuard.
//


#ifndef RTSPRESPONSE_INCLUDED
#define RTSPRESPONSE_INCLUDED

/*
Response    =     Status-Line         ; Section 7.1
                 *(    general-header      ; Section 5
                 |     response-header     ; Section 7.1.2
                 |     entity-header )     ; Section 8.1
                       CRLF
                       [ message-body ]    ; Section 4.3

*/
/*
Status-Line =   RTSP-Version SP Status-Code SP Reason-Phrase CRLF
*/
/*
	response-header  =     Location             ; Section 12.25
                    |     Proxy-Authenticate   ; Section 12.26
                    |     Public               ; Section 12.28
                    |     Retry-After          ; Section 12.31
                    |     Server               ; Section 12.36
                    |     Vary                 ; Section 12.42
                    |     WWW-Authenticate     ; Section 12.44
*/

/*	
   Status-Code  =     "100"      ; Continue
                |     "200"      ; OK
                |     "201"      ; Created
                |     "250"      ; Low on Storage Space
                |     "300"      ; Multiple Choices
                |     "301"      ; Moved Permanently
                |     "302"      ; Moved Temporarily
                |     "303"      ; See Other
                |     "304"      ; Not Modified
                |     "305"      ; Use Proxy
                |     "400"      ; Bad Request
                |     "401"      ; Unauthorized
                |     "402"      ; Payment Required
                |     "403"      ; Forbidden
                |     "404"      ; Not Found
                |     "405"      ; Method Not Allowed
                |     "406"      ; Not Acceptable
                |     "407"      ; Proxy Authentication Required
                |     "408"      ; Request Time-out
                |     "410"      ; Gone
                |     "411"      ; Length Required
                |     "412"      ; Precondition Failed
                |     "413"      ; Request Entity Too Large
                |     "414"      ; Request-URI Too Large
                |     "415"      ; Unsupported Media Type
                |     "451"      ; Parameter Not Understood
                |     "452"      ; Conference Not Found
                |     "453"      ; Not Enough Bandwidth
                |     "454"      ; Session Not Found
                |     "455"      ; Method Not Valid in This State
                |     "456"      ; Header Field Not Valid for Resource
                |     "457"      ; Invalid Range
                |     "458"      ; Parameter Is Read-Only
                |     "459"      ; Aggregate operation not allowed
                |     "460"      ; Only aggregate operation allowed
                |     "461"      ; Unsupported transport
                |     "462"      ; Destination unreachable
                |     "500"      ; Internal Server Error
                |     "501"      ; Not Implemented
                |     "502"      ; Bad Gateway
                |     "503"      ; Service Unavailable
                |     "504"      ; Gateway Time-out
                |     "505"      ; RTSP Version not supported
                |     "551"      ; Option not supported
                |     extension-code
*/


#include "base.h"
#include "RTSPMessage.h"
#include "poco/Timestamp.h"

using Poco::Timestamp;
/**
	RTSPResponse for class
*/

class BASE_API RTSPResponse: public RTSPMessage
{
public:
	enum RTSPStatus
	{
		RTSP_CONTINUE                        = 100,
		RTSP_SWITCHING_PROTOCOLS             = 101,
		RTSP_OK                              = 200,
		RTSP_CREATED                         = 201,
		RTSP_ACCEPTED                        = 202,
		RTSP_NONAUTHORITATIVE                = 203,
		RTSP_NO_CONTENT                      = 204,
		RTSP_RESET_CONTENT                   = 205,
		RTSP_PARTIAL_CONTENT                 = 206,
		RTSP_MULTIPLE_CHOICES                = 300,
		RTSP_MOVED_PERMANENTLY               = 301,
		RTSP_FOUND                           = 302,
		RTSP_SEE_OTHER                       = 303,
		RTSP_NOT_MODIFIED                    = 304,
		RTSP_USEPROXY                        = 305,
		// UNUSED: 306
		RTSP_TEMPORARY_REDIRECT              = 307,
		RTSP_BAD_REQUEST                     = 400,
		RTSP_UNAUTHORIZED                    = 401,
		RTSP_PAYMENT_REQUIRED                = 402,
		RTSP_FORBIDDEN                       = 403,
		RTSP_NOT_FOUND                       = 404,
		RTSP_METHOD_NOT_ALLOWED              = 405,
		RTSP_NOT_ACCEPTABLE                  = 406,
		RTSP_PROXY_AUTHENTICATION_REQUIRED   = 407,
		RTSP_REQUEST_TIMEOUT                 = 408,
		RTSP_CONFLICT                        = 409,
		RTSP_GONE                            = 410,
		RTSP_LENGTH_REQUIRED                 = 411,
		RTSP_PRECONDITION_FAILED             = 412,
		RTSP_REQUESTENTITYTOOLARGE           = 413,
		RTSP_REQUESTURITOOLONG               = 414,
		RTSP_UNSUPPORTEDMEDIATYPE            = 415,
		RTSP_REQUESTED_RANGE_NOT_SATISFIABLE = 416,
		RTSP_EXPECTATION_FAILED              = 417,
		RTSP_INTERNAL_SERVER_ERROR           = 500,
		RTSP_NOT_IMPLEMENTED                 = 501,
		RTSP_BAD_GATEWAY                     = 502,
		RTSP_SERVICE_UNAVAILABLE             = 503,
		RTSP_GATEWAY_TIMEOUT                 = 504,
		RTSP_VERSION_NOT_SUPPORTED           = 505
	};

	RTSPResponse();
	RTSPResponse(RTSPStatus status, const std::string& reason);
	RTSPResponse(const std::string& version, RTSPStatus status, const std::string& reason);
	RTSPResponse(RTSPStatus status);
	RTSPResponse(const std::string& version, RTSPStatus status);
	virtual ~RTSPResponse();
	void setStatus(RTSPStatus status);
	RTSPStatus getStatus() const;
	void setStatus(const std::string& status);
	void setReason(const std::string& reason);
	const std::string& getReason() const;
	void setStatusAndReason(RTSPStatus status, const std::string& reason);
	void setStatusAndReason(RTSPStatus status);

	void setPublic(const std::string& pub);
	void setPublic();
	const std::string& getPublic() const;
	
	void write(std::ostream& ostr) const;
	void read(std::istream& istr);

	void clear();

public:
	static const std::string& getReasonForStatus(RTSPStatus status);
	static const std::string RTSP_REASON_CONTINUE;
	static const std::string RTSP_REASON_SWITCHING_PROTOCOLS;
	static const std::string RTSP_REASON_OK;
	static const std::string RTSP_REASON_CREATED;
	static const std::string RTSP_REASON_ACCEPTED;
	static const std::string RTSP_REASON_NONAUTHORITATIVE;
	static const std::string RTSP_REASON_NO_CONTENT;
	static const std::string RTSP_REASON_RESET_CONTENT;
	static const std::string RTSP_REASON_PARTIAL_CONTENT;
	static const std::string RTSP_REASON_MULTIPLE_CHOICES;
	static const std::string RTSP_REASON_MOVED_PERMANENTLY;
	static const std::string RTSP_REASON_FOUND;
	static const std::string RTSP_REASON_SEE_OTHER;
	static const std::string RTSP_REASON_NOT_MODIFIED;
	static const std::string RTSP_REASON_USEPROXY;
	static const std::string RTSP_REASON_TEMPORARY_REDIRECT;
	static const std::string RTSP_REASON_BAD_REQUEST;
	static const std::string RTSP_REASON_UNAUTHORIZED;
	static const std::string RTSP_REASON_PAYMENT_REQUIRED;
	static const std::string RTSP_REASON_FORBIDDEN;
	static const std::string RTSP_REASON_NOT_FOUND;
	static const std::string RTSP_REASON_METHOD_NOT_ALLOWED;
	static const std::string RTSP_REASON_NOT_ACCEPTABLE;
	static const std::string RTSP_REASON_PROXY_AUTHENTICATION_REQUIRED;
	static const std::string RTSP_REASON_REQUEST_TIMEOUT;
	static const std::string RTSP_REASON_CONFLICT;
	static const std::string RTSP_REASON_GONE;
	static const std::string RTSP_REASON_LENGTH_REQUIRED;
	static const std::string RTSP_REASON_PRECONDITION_FAILED;
	static const std::string RTSP_REASON_REQUESTENTITYTOOLARGE;
	static const std::string RTSP_REASON_REQUESTURITOOLONG;
	static const std::string RTSP_REASON_UNSUPPORTEDMEDIATYPE;
	static const std::string RTSP_REASON_REQUESTED_RANGE_NOT_SATISFIABLE;
	static const std::string RTSP_REASON_EXPECTATION_FAILED;
	static const std::string RTSP_REASON_INTERNAL_SERVER_ERROR;
	static const std::string RTSP_REASON_NOT_IMPLEMENTED;
	static const std::string RTSP_REASON_BAD_GATEWAY;
	static const std::string RTSP_REASON_SERVICE_UNAVAILABLE;
	static const std::string RTSP_REASON_GATEWAY_TIMEOUT;
	static const std::string RTSP_REASON_VERSION_NOT_SUPPORTED;
	static const std::string RTSP_REASON_UNKNOWN;
	
	static const std::string DATE;
	static const std::string SET_COOKIE;

private:
	enum Limits
	{
		MAX_VERSION_LENGTH = 8,
		MAX_STATUS_LENGTH  = 3,
		MAX_REASON_LENGTH  = 512
	};
	
	RTSPStatus  _status;
	std::string _reason;
	
	RTSPResponse(const RTSPResponse&);
	RTSPResponse& operator = (const RTSPResponse&);
};
//
// inlines
//
inline RTSPResponse::RTSPStatus RTSPResponse::getStatus() const
{
	return _status;
}


inline const std::string& RTSPResponse::getReason() const
{
	return _reason;
}


#endif